package com.zhs.base.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhs.base.config.properties.TencentMapProperties;
import com.zhs.base.dto.GeoCodeDto;
import com.zhs.base.dto.GeoInfoDto;
import com.zhs.base.service.BaseMapApiService;
import com.zhs.base.service.MapApiService;
import com.zhs.base.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.Objects;

/**
 * 腾讯
 *
 * @author Java架构师之旅
 * @version 1.0
 * @date 2022年08月16日 17:17.
 */
@Slf4j
public class TencentMapApiService extends BaseMapApiService implements MapApiService {
    private TencentMapProperties tencentMapProperties;

    public void setTencentMapProperties(final TencentMapProperties tencentMapProperties) {
        this.tencentMapProperties = tencentMapProperties;
    }

    @Override
    public GeoCodeDto getGeocode(String address) {
        log.info("【地址编码 腾讯】入参: address={}", address);
        try {
            String getGeocoderLatitudeUrl = getGeocoderLatitudeMapUrl(super.encode(address));
            return super.defaultDealReturnJson(HttpClientUtils.get(getGeocoderLatitudeUrl));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private String getGeocoderLatitudeMapUrl(final String address) {
        return tencentMapProperties.getTencentGeoUrl() + address + "&key=" + tencentMapProperties.getTencentKey();
    }

    @Override
    public GeoInfoDto getAddress(final GeoCodeDto geoCodeDto) {
        log.info("【逆地址编码 腾讯】入参,geoCodeDto={}", JSON.toJSONString(geoCodeDto));
        String urlString = getAddUrl(geoCodeDto);
        try {
            final GeoInfoDto res = dealReturnAddJson(HttpClientUtils.get(urlString));
            log.info("【逆地址编码】res={}", JSON.toJSONString(res));
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private GeoInfoDto dealReturnAddJson(final String res) throws RuntimeException {
        if (StringUtils.isNotBlank(res)) {
            JSONObject jsonObject = JSON.parseObject(res);
            String status = jsonObject.getString("status");
            if (Objects.equals(NumberUtils.INTEGER_ZERO, Integer.valueOf(status))) {
                JSONObject jsonObject_ = JSON.parseObject(jsonObject.getString("result"));
                final GeoInfoDto geoInfoDto = new GeoInfoDto();
                geoInfoDto.setAddress(jsonObject_.getString("address"));
                JSONObject address_component = JSON.parseObject(jsonObject_.getString("address_component"));

                if (null != address_component) {
                    geoInfoDto.setProvince(address_component.getString("province"));
                    geoInfoDto.setCity(address_component.getString("city"));
                    geoInfoDto.setDistrict(address_component.getString("district"));
                    geoInfoDto.setStreet(address_component.getString("street"));
                    geoInfoDto.setStreetNumber(address_component.getString("street_number"));
                }
                JSONObject address_reference = JSON.parseObject(jsonObject_.getString("address_reference"));
                JSONObject town = JSON.parseObject(address_reference.getString("town"));
                if (null != town) {
                    geoInfoDto.setTownship(town.getString("title"));
                }
                log.info("【逆地址编码】 成功 geoInfoDto={}", JSON.toJSONString(geoInfoDto));
                return geoInfoDto;
            }
            log.warn("【逆地址编码】 失败 status={} | message={}", status, jsonObject.getString("message"));
            throw new RuntimeException(jsonObject.getString("message"));
        }
        return null;
    }

    private String getAddUrl(final GeoCodeDto geoCodeDto) {
        return tencentMapProperties.getTencentReGeoUrl() + geoCodeDto.getLat() + "," + geoCodeDto.getLng() + "&key=" + tencentMapProperties.getTencentKey();
    }

    @Override
    public Integer getWeight() {
        return tencentMapProperties.getWeight();
    }
}
